#include "Camera.h"
#include <glm/gtx/transform.hpp>


Camera::Camera ()
{
// 	setIsRender (isRenderCamera);
	resetCamera ();
}



Camera::~Camera ()
{
}



// void Camera::_onRender ()
// {
// 	glPushMatrix ();
// 	glScalef (1, 1, 2);
// 	glutSolidCube (1);
// 	glPopMatrix ();
// }
// 
// 
// 
// void Camera::__onUpdate (float elapsedSeconds)
// {
// }

glm::mat4 Camera::getMatrix () const
{
	return glm::translate< float > (0, 0, -_distance) *
			glm::rotate (-_vAngle, glm::vec3 (1, 0, 0)) * 
			glm::rotate (-_hAngle, glm::vec3 (0, 1, 0)) *
			glm::translate< float > (-_viewpoint) * _baseMatrix;
}

void Camera::rotateCamera (float angle, RotatePlane rotatePlane)
{
	if (rotatePlane == H)
		setCameraAngle (_hAngle + angle, _vAngle);
	else
		setCameraAngle (_hAngle, _vAngle + angle);

}

void Camera::setCameraAngle (float hAngle, float vAngle)
{
	_hAngle = hAngle;
	_vAngle = vAngle;
// 	_updateMatrix ();
}

void Camera::setDistance (float distance)
{
	_distance = distance;
	if (_distance < 0)
		_distance = 0;
// 	_updateMatrix ();
}

void Camera::moveFar (float deltaDistance)
{
	setDistance (_distance * deltaDistance);
}

void Camera::moveNear (float deltaDistance)
{
	setDistance (_distance / deltaDistance);
}

void Camera::resetCamera ()
{
// 	resetTransformMatrix ();
	setDistance (10);
	setViewpoint (glm::vec3 ());
	_hAngle = 45;
	_vAngle = -45;
	_baseMatrix = glm::mat4 ();
// 	_updateMatrix ();
}

// void Camera::_updateMatrix ()
// {
// 	resetTransformMatrix ();
// 	rotate (_hAngle, glm::vec3 (0.0, 1.0, 0.0));
// 	rotate (_vAngle, glm::vec3 (1.0, 0.0, 0.0));
// 	translate (glm::vec3 (0.0, 0.0, _distance));
// }

float Camera::getDistance () const
{
	return _distance;
}

float Camera::getHAngle () const
{
	return _hAngle;
}

float Camera::getVAngle () const
{
	return _vAngle;
}

// glm::vec3 Camera::getCameraLocation ()
// {
// 	glm::mat4 globalMat = getGlobalMatrix ();
// 	return glm::vec3 (globalMat[3][0], globalMat[3][1], globalMat[3][2]);
// }
// 
void Camera::setViewpoint (const glm::vec3 & loc)
{
	_viewpoint = loc;
}

glm::vec3 Camera::getViewpoint () const
{
	return _viewpoint;
}

void Camera::moveViewPointReletedToCamera (const glm::vec3 & vec)
{
	_viewpoint += glm::vec3 ((glm::inverse (glm::rotate (-_vAngle, glm::vec3 (1, 0, 0)) * 
			glm::rotate (-_hAngle, glm::vec3 (0, 1, 0))) * glm::vec4 (vec, 0.0)).
			swizzle (glm::X, glm::Y, glm::Z));

}

void Camera::setBaseMatrix (const glm::mat4 &baseMatrix)
{
	_baseMatrix = baseMatrix;
}
